﻿using Fasterflect;
using System;
using System.Linq;
using System.Linq.Expressions;

namespace HobSoft.SoccerBet2014.Common.Queryable
{
    public static class QueryableExtensions
    {
        public static IQueryable<TEntity> Sort<TEntity>(this IQueryable<TEntity> query, params ISortExpression<TEntity>[] sortExpressions)
            where TEntity : class
        {
            if (sortExpressions == null)
                return query;

            IOrderedQueryable<TEntity> output = null;

            foreach (var orderByExpression in sortExpressions)
            {
                if (output == null)
                    output = orderByExpression.ApplyOrderBy(query);
                else
                    output = orderByExpression.ApplyThenBy(output);
            }

            return output ?? query;
        }


        public static IQueryable<TEntity> Update<TEntity>(this IQueryable<TEntity> models, Expression<Func<TEntity, TEntity>> updateExpression)
            where TEntity : class
        {
            var lambda = updateExpression.Compile();
            MemberInitExpression memberInitExpression = updateExpression.Body as MemberInitExpression;
            foreach (var mod in models)
            {
                var upRet = lambda.DynamicInvoke(mod);
                foreach (MemberBinding binding in memberInitExpression.Bindings)
                {
                    var pinfo = binding.Member as System.Reflection.PropertyInfo;
                    var pname = binding.Member.Name;
                    if (pinfo == null) continue;
                    var value = upRet.TryGetPropertyValue(pname);
                    if (pinfo.DeclaringType.IsValueType && value == null) continue;
                    mod.TrySetPropertyValue(pname, value);
                }
            }
            return models;
        }
    }
}
